package cn.sylinx.hbatis.ext.starter.util;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import cn.sylinx.hbatis.db.common.FS;
import cn.sylinx.hbatis.db.common.ITransaction;
import cn.sylinx.hbatis.db.common.Page;
import cn.sylinx.hbatis.ext.mirage.repository.DaoService;
import cn.sylinx.hbatis.kit.Ret;
import cn.sylinx.hbatis.plugin.datasource.JdbcResourcePlugin;

public class DefaultSimpleDaoService implements SimpleDaoService {

	private static final Map<String, SimpleDaoService> dbServiceMap = new WeakHashMap<String, SimpleDaoService>();

	private String ds = null;

	public DefaultSimpleDaoService() {
		this(JdbcResourcePlugin.DEFAULT_JDBC_RESOURCE_NAME);
	}

	protected DefaultSimpleDaoService(String ds) {
		this.ds = ds;
		dbServiceMap.put(ds, this);
	}

	@Override
	public SimpleDaoService ds(String ds) {

		if (ds == null || "".equals(ds.trim())) {
			return dbServiceMap.get(JdbcResourcePlugin.DEFAULT_JDBC_RESOURCE_NAME);
		}

		SimpleDaoService dbService = dbServiceMap.get(ds);
		if (dbService == null) {

			synchronized (ds.intern()) {
				createInstanceInner(ds);
			}

			dbService = dbServiceMap.get(ds);
		}

		return dbService;

	}

	private void createInstanceInner(String ds) {

		SimpleDaoService dbService = dbServiceMap.get(ds);
		if (dbService == null) {
			dbService = createInstance(ds);
			dbServiceMap.put(ds, dbService);
		}
	}

	protected SimpleDaoService createInstance(String ds) {
		return new DefaultSimpleDaoService(ds);
	}

	@Override
	public <T> List<T> query(FS<T> fluentSql) {
		return create().query(fluentSql);
	}

	@Override
	public <T, R> List<R> queryObject(FS<T> fluentSql) {
		return create().queryObject(fluentSql);
	}

	@Override
	public <T> List<T> queryWithCache(FS<T> fluentSql) {
		return create().queryWithCache(fluentSql);
	}

	@Override
	public <T> T queryFirst(FS<T> fluentSql) {
		return create().queryFirst(fluentSql);
	}

	@Override
	public <T> T queryFirstWithCache(FS<T> fluentSql) {
		return create().queryFirstWithCache(fluentSql);
	}

	@Override
	public <T, R> R queryFirstObject(FS<T> fluentSql) {
		return create().queryFirstObject(fluentSql);
	}

	@Override
	public int update(FS<?> fluentSql) {
		return create().update(fluentSql);
	}

	@Override
	public int delete(FS<?> fluentSql) {
		return create().delete(fluentSql);
	}

	@Override
	public int count(FS<?> fluentSql) {
		return create().count(fluentSql);
	}

	@Override
	public Serializable insert(FS<?> fluentSql) {
		return create().insert(fluentSql);
	}

	@Override
	public <T> Page<T> queryPage(FS<T> fluentSql, int pageNumber, int pageSize) {
		return create().queryPage(fluentSql, pageNumber, pageSize);
	}

	@Override
	public <T> int update(T t) {
		return create().update(t);
	}

	@Override
	public <T> int delete(T t) {
		return create().delete(t);
	}

	@Override
	public <T> int deleteByPk(Object id, Class<T> clz) {
		return create().deleteByPk(id, clz);
	}

	@Override
	public <T> T get(Object id, Class<T> clz) {
		return create().get(id, clz);
	}

	@Override
	public <T> Serializable addObject(T t) {
		return create().addObject(t);
	}

	@Override
	public <T> boolean justAdd(T t) {
		return create().justAdd(t);
	}

	@Override
	public <T> Ret addWithRet(T t) {
		return create().addWithRet(t);
	}

	@Override
	public boolean transaction(ITransaction transactions) {
		return create().transaction(transactions);
	}

	@Override
	public Ret transactionWithReturn(ITransaction transactions) {
		return create().transactionWithReturn(transactions);
	}

	@Override
	public DaoService create() {
		return DaoHelper.create(ds);
	}

	@Override
	public <T> FS<T> createFS(Class<T> clazz) {
		return create().createFS(clazz);
	}

}
